import json
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import pymysql
from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources=r'/*')


def calculate_cosine_similarity(json_str, database_data):
    threshold = 0.3  # 阈值，表示共有的key的个数占比
    data = []
    for row in database_data:
        data.append(row['assess_data'])

    # 解析传入的JSON字符串，获取第一层子元素的key
    json_data = json.loads(json_str)
    json_keys = set(json_data.keys())

    similar_data = []
    for row in data:
        row_data = json.loads(row)
        row_keys = set(row_data.keys())
        common_keys = json_keys.intersection(row_keys)
        # 如果相同键的占比超过预设的阈值，就保留，等到下一步计算
        if len(common_keys) / len(json_keys) >= threshold:
            similar_data.append(json.dumps(row_data))

    # 计算传入json字符串与每个评估数据的余弦相似度
    vectorizer = TfidfVectorizer()
    tfidf_matrix = vectorizer.fit_transform([json_str] + similar_data)
    similarity_matrix = cosine_similarity(tfidf_matrix[0], tfidf_matrix[1:])[0]

    # 获取与传入json字符串相似度最高的3条数据所对应的推荐方案和相似度
    top_indices = similarity_matrix.argsort()[-3:][::-1]
    recommendations = []
    similarities = []
    for i, row in enumerate(database_data):
        if i in top_indices:
            recommendations.append(row['recommend_scheme'])
            similarities.append(similarity_matrix[i])

    return recommendations, similarities


@app.route('/similarity', methods=['POST'])
def execute_recommend():
    # 接收传入的字符串
    new_json_str = request.form.get('file')
    # 连接数据库
    connection = pymysql.connect(host='localhost', user='root', password='lsn123', db='ruoyi-vue')
    try:
        with connection.cursor() as cursor:
            # 获取数据库中的所有数据
            sql = "select assess_data,recommend_scheme from gx_assess_data"
            cursor.execute(sql)
            database_data = []
            for row in cursor.fetchall():
                # Create a dictionary with only the necessary columns
                data = {
                    'assess_data': row[0],
                    'recommend_scheme': row[1]
                }
                database_data.append(data)
            # 计算传入数据与数据库中所有数据的相似度
            recommendations, similarities = calculate_cosine_similarity(new_json_str, database_data)
            # print(f"Similarity between input data and {recommendations}: {similarities}")
    finally:
        connection.close()

    # 前端需要将['111','222']转换成[{'recommend','111'},{'recommend','222'}]的形式
    result = [{'recommend': item} for item in recommendations]
    # 输出与传入json数据相似度最高的3条数据所对应的推荐方案
    for i, recommendation in enumerate(recommendations):
        print(f"推荐方案{i + 1}：{recommendation}")
        print(f"相似度：{similarities[i]}")
        print()
    return result


if __name__ == '__main__':
    app.run(port=5001, debug=True)
